package com.atguigu.tingshu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.concurrent.CompletableFuture;

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源自动配置
@EnableDiscoveryClient
@EnableFeignClients
@EnableAsync
public class ServiceSearchApplication {

    /**
     * 创建异步任务
     * CompletableFuture内部包含内置线程池forkJoin不使用
     * CompletableFuture.runAsync() 异步任务不依赖其他任务，当前任务不需要返回结果
     * CompletableFuture.supplyAsync() 异步任务不依赖其他任务，当前任务有返回结果
     * <p>
     * 异步任务对象调用方法
     * 其他异步任务对象.thenApplyAsync()  获取被依赖任务执行结果，当前任务有返回结果
     * 其他异步任务对象.thenAcceptAsync()  获取被依赖任务执行结果，当前任务无返回结果
     *
     * 组合异步任务
     *  anyOf（）.join() 只要任意任务执行完毕主线程继续
     *  allOf（）.join() 只要所有任务执行完毕主线程继续
     *
     *
     * @param args
     */
    public static void main(String[] args) {
        //1. 创建异步任务对象-任务A 不需要依赖其他任务，需要返回结果给B,C任务使用
        CompletableFuture<String> completableFutureA = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + ",异步任务A执行了");
            return "resultA"; //异步任务A执行结果
        });

        //2. 基于异步任务A创建异步任务B,依赖A任务执行结果，当前任务不需要返回值
        CompletableFuture<Void> completableFutureB = completableFutureA.thenAcceptAsync(aResult -> {
            System.out.println(Thread.currentThread().getName() + ",异步任务B执行了，获取到A的结果：" + aResult);
        });

        //3. 基于异步任务A创建异步任务C
        CompletableFuture<Void> completableFutureC = completableFutureA.thenAcceptAsync(aResult -> {
            System.out.println(Thread.currentThread().getName() + ",异步任务C执行了，获取到A的结果：" + aResult);
        });


        //新增异步任务D 不依赖任何异步任务 不需要有返回值
        CompletableFuture<Void> completableFutureD = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + ",异步任务D执行了");
        });


        //4. 组合异步任务，主线程阻塞等待所有异步任务执行完毕，主线程才继续
        CompletableFuture.allOf(
                completableFutureA,
                completableFutureB,
                completableFutureC,
                completableFutureD
        ).join();


        System.out.println(Thread.currentThread().getName()+"主线程执行");


        SpringApplication.run(ServiceSearchApplication.class, args);


    }

}
